package com.qianbao.finance.sync.modules.elasticsearch.websocket.server;

import static org.jboss.netty.channel.Channels.pipeline;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

import com.qianbao.finance.sync.common.utils.SpringContextUtils;
import com.qianbao.finance.sync.modules.elasticsearch.websocket.simulator.ZBXServerSimulator;
import org.apache.log4j.Logger;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;


/**
 * Netty Socket Server
 * 
 * @author WangYuan
 * @date 2016年7月18日上午10:55:44
 */
public class Server {

    static {
        System.setProperty("log4j.configurationFile", "log4j2.xml");
    }

    private static int nettyBossThreadId = 0;
    private static int nettyWorkerThreadId = 0;
    private final static Logger logger = Logger.getLogger(Server.class);

    private static synchronized int getNextBettyBossThreadId() {
        return nettyBossThreadId++;
    }

    private static synchronized int getNettyWorkerThreadId() {
        return nettyWorkerThreadId++;
    }
    private static ShareConfig shareConfig = (ShareConfig) SpringContextUtils.getBean("shareConfig");
    public static void bootstrap(){
        //ShareConfig.getInstance().doStart();
        ShareBean.getInstance().doStart();

        /*
         * Subscriber subscriber = new Subscriber(); Thread subThread = new
         * Thread(subscriber,"订阅线程");
         */

/*        ZBXServerSimulator simulator = new ZBXServerSimulator();
        Thread subThread = new Thread(simulator, "订阅线程");*/

        final ChannelFactory factory =
                new NioServerSocketChannelFactory(
                        Executors.newCachedThreadPool(new ThreadFactory() {
                            @Override
                            public Thread newThread(Runnable runnable) {
                                Thread thread = new Thread(runnable);
                                thread.setName("Netty主线程" + getNextBettyBossThreadId());
                                return thread;
                            }
                        }), Executors.newCachedThreadPool(new ThreadFactory() {
                    @Override
                    public Thread newThread(Runnable runnable) {
                        Thread thread = new Thread(runnable);
                        thread.setName("Netty工作线程" + getNettyWorkerThreadId());
                        return thread;
                    }
                }));
        final ServerBootstrap serverBootstrap = new ServerBootstrap(factory);
        final Handler handler = new Handler();
        serverBootstrap.setPipelineFactory(new ChannelPipelineFactory() {
            @Override
            public ChannelPipeline getPipeline() throws Exception {
                ChannelPipeline pipeline = pipeline();
                pipeline.addLast("decoder", new HttpRequestDecoder());
                pipeline.addLast("aggregator", new HttpChunkAggregator(65536));
                pipeline.addLast("encoder", new HttpResponseEncoder());
                pipeline.addLast("handler", handler);
                return pipeline;
            }
        });

        final Channel bind =
                serverBootstrap.bind(new InetSocketAddress(shareConfig.getPort()));
        logger.info("socket-server 启动成功,监听端口: " + shareConfig.getPort());

        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                bind.close().awaitUninterruptibly();
                serverBootstrap.releaseExternalResources();
                ShareBean.getInstance().doStop();
                // FlashPolicyServer.stop();
                // subscriber.doStop();
            }
        });
        /*subThread.start();*/
    }

    public static void main(String[] args) {
        Server.bootstrap();
    }
}
